package zsl.utils;

public class TimeEstimator {
	
	
	/**
	 * @param a estimated slop factor taTime = a*depth*ListNum^2
	 * @param k topk num
	 * @param n # of words
	 * @param l # of list
	 * @param u expection
	 * @param d deviation
	 * @param mArray array of # of list to merge
	 * @return an array of estimated ta time cost
	 */
	public static double[] estimateTA(double a, int k, int n, int l, double u, double d, int[] mArray){
		double[] result = new double[mArray.length];
		for (int i = 0; i < result.length; i++) {
			result[i] = estimate(a, k, n, l, u, d, mArray[i]);
		}
		return result;
	}
	
	private static double estimate(double a, int k, int n, int l, double u, double d, int m){
		return a * getDepth(k, n, l, u, d, m) * l/m * l/m ;
	}
	
	/**
	 * @param k topk num
	 * @param n # of words
	 * @param l # of list
	 * @param u expection
	 * @param d deviation
	 * @return value of estimated k-th largest word
	 * 
	 * (Xt - lu)/(l*d)^0.5 = NormDistTable.getX(1-k/n)
	 * 
	 */
	private static double getXt(int k, int n, int l, double u, double d){
		return Math.sqrt(l*d)*NormalDistTable.getX(1-k/(double)n) + l*u;
	}
	
	
	/**
	 * @param k topk num
	 * @param n # of words
	 * @param l # of list
	 * @param u expection
	 * @param d deviation
	 * @param m # of list to merge
	 * @return value of estimated threshold in each merged list
	 */
	private static double getXm(int k, int n, int l, double u, double d, int m){
		return getXt(k, n, l, u, d)* m / l;
	}
	
	/**
	 * @param k topk num
	 * @param n # of words
	 * @param l # of list
	 * @param u expection
	 * @param d deviation
	 * @param m # of list to merge
	 * @return estimated access depth of each merged list
	 */
	private static double getDepth(int k, int n, int l, double u, double d, int m) {
		double x = (getXm(k, n, l, u, d, m) - m*u)/Math.sqrt(m*d);
		double fai = NormalDistTable.selfCaculate(x);
		double depth = n *(1 - fai);
		return depth;
	}
	
	public static void main(String[] args) {
		double a = 0.00005;
		int k = 10;
		int n = 1000;
		int l =2000; //# of list
		double u = 1500; // expection per list
		double d = 3000*3000/12.0; //deviation per list
		int[] mArray = {1000,667,500,400,334,286,250,223,200,182,167,154,143,134,125,118,112,106,100,96,91,87,84,80,77,75,72,69,67,65,63,61,59,58,56,55,53,52,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2};
		double[] result = estimateTA(a, k, n, l, u, d, mArray);
		
		for (int i = 0; i < result.length; i++) {
			System.out.println(result[i]);
		}
		
		System.out.println("=============test================");
		//test getXt()
		System.out.println(getXt(k, n, l, u, d));
		//test getXm()
		System.out.println(getXm(k, n, l, u, d, 2));
		
		System.out.println(estimate(a, k, n, l, u, d, 2));
	}
	
	
}
